import { IContext, IEntityLocalDataService, IParam } from '@/core';
import { I{{pascalCase appEntity.codeName}} } from '../interface/i-{{spinalCase appEntity.codeName}}';
import keys from '../{{spinalCase appEntity.codeName}}-keys';
{{ImportDtoHelp appEntity}}

{{#each appEntity.allPSAppDEMethodDTOs as | dto |}}
{{#eq dto.type 'DEFAULT'}}
/**
 * {{dto.name}}DTO辅助类
 * 基于template/src/api/\{{appEntities}}/data-service/\{{appEntities}}-help.ts.hbs生成  
 *
 * @export
 * @class {{pascalCase dto.codeName}}Help
 */
export class {{pascalCase dto.codeName}}Help {

    /**
     * 获取实体数据服务
     *
     * @static
     * @param {IParam} context
     * @return {*}  {Promise<IEntityLocalDataService<I{{pascalCase appEntity.codeName}}>>}
     * @memberof {{pascalCase dto.codeName}}Help
     */
    public static async getService(context: IParam): Promise<IEntityLocalDataService<I{{pascalCase appEntity.codeName}}>> {
        return App.getDataService('{{pascalCase appEntity.codeName}}', context);
    }

    /**
     * 获取是否缓存
     *
     * @memberof {{pascalCase dto.codeName}}Help
     */
    public static getEnableCache(){
        return {{#eq appEntity.storageMode 4}}true{{else}}false{{/eq}};
    }

    /**
     * DTO转化成数据对象
     *
     * @static
     * @param {IContext} context 应用上下文
     * @param {IParam} source dto对象
     * @return {*} 
     * @memberof {{pascalCase dto.codeName}}Help
     */
    public static async toDataObj(context: IContext, source: IParam) {
        const _data: any = {};
    {{#each dto.psAppDEMethodDTOFields as | dtoField |}}
        {{#if dtoField.type}}
            {{#or (and dtoField.type 'SIMPLE') (and dtoField.type 'SIMPLES')}}
                {{#if dtoField.psAppDEField}}
        //  {{dtoField.logicName}}
        _data.{{lowerCase dtoField.psAppDEField.codeName}} = source.{{lowerCase dtoField.codeName}};
                {{/if}}
            {{/or}}
            {{#eq dtoField.type 'DTOS'}}
                {{#if dtoField.refPSAppDEMethodDTO}}
        //  {{lowerCase dtoField.codeName}}
        if({{pascalCase dtoField.refPSAppDEMethodDTO.codeName}}Help.getEnableCache()){
            if (source && source.{{lowerCase dtoField.codeName}} && source.{{lowerCase dtoField.codeName}}.length > 0) {
                await {{pascalCase dtoField.refPSAppDEMethodDTO.codeName}}Help.setCacheDataArray(context, source.{{lowerCase dtoField.codeName}});
            }
        }else{
            _data.{{lowerCase dtoField.codeName}} = source.{{lowerCase dtoField.codeName}};
        }
                {{/if}}
            {{/eq}}
            {{#eq dtoField.type 'DTO'}}
                {{#if dtoField.refPSAppDEMethodDTO}}
        //  {{lowerCase dtoField.codeName}}
        if({{pascalCase dtoField.refPSAppDEMethodDTO.codeName}}Help.getEnableCache()){
        if (source && source.{{lowerCase dtoField.codeName}}) {
            await {{pascalCase dtoField.refPSAppDEMethodDTO.codeName}}Help.setCacheData(context, source.{{lowerCase dtoField.codeName}});
        }
        }else{
            _data.{{lowerCase dtoField.codeName}} = source.{{lowerCase dtoField.codeName}};
        }
                {{/if}}
            {{/eq}}
        {{/if}}
    {{/each}}
        //  处理预置字段（以srf开头）
        if (source && Object.keys(source).length > 0) {
            Object.keys(source).forEach((key:string) =>{
                if(key.startsWith('srf')){
                    _data[key] = source[key];
                }
            })
        }
        return _data;
    }

    /**
     * 转化数据（DTO转化成数据对象）
     *
     * @static
     * @param {IContext} context 应用上下文
     * @param {IParam} data 数据对象
     * @return {*} 
     * @memberof {{pascalCase dto.codeName}}Help
     */
    public static async toDataObjArray(context: IContext, data: any[]) {
        const _data: any[] = [];
        if (data && Array.isArray(data) && data.length > 0) {
            for (let i = 0; i < data.length; i++) {
                const tempdata = await this.toDataObj(context, data[i]);
                _data.push(tempdata);
            }
        }
        return _data;
    }

    /**
     * 数据对象转化成DTO
     *
     * @static
     * @param {IContext} context 应用上下文
     * @param {IParam} source 数据对象
     * @return {*} 
     * @memberof {{pascalCase dto.codeName}}Help
     */
    public static async toDto(context: IContext, source: IParam) {
        const _data: any = {};
        const excludes: string[] = [{{#each dto.psAppDEMethodDTOFields as | dtoField |}}{{#or (eq dtoField.type 'DTOS') (eq dtoField.type 'DTO')}}'{{lowerCase dtoField.codeName}}'{{#unless @last}}, {{/unless}}{{/or}}{{/each}}];
    {{#each dto.psAppDEMethodDTOFields as | dtoField |}}
        {{#if dtoField.type}}
            {{#or (and dtoField.type 'SIMPLE') (and dtoField.type 'SIMPLES')}}
                {{#if dtoField.psAppDEField}}
        //  {{dtoField.logicName}}
        if(source.hasOwnProperty('{{lowerCase dtoField.psAppDEField.codeName}}')){
            _data.{{lowerCase dtoField.codeName}} = source.{{lowerCase dtoField.psAppDEField.codeName}};
        }
                {{/if}}
            {{/or}}
            {{#eq dtoField.type 'DTOS'}}
                {{#if dtoField.refPSAppDEMethodDTO}}
        //  {{lowerCase dtoField.codeName}}
        if({{pascalCase dtoField.refPSAppDEMethodDTO.codeName}}Help.getEnableCache()){
            _data.{{lowerCase dtoField.codeName}} = await {{pascalCase dtoField.refPSAppDEMethodDTO.codeName}}Help.getCacheDataArray(context);
        }else{
            if(source.hasOwnProperty('{{lowerCase dtoField.codeName}}')){
                _data.{{lowerCase dtoField.codeName}} = source.{{lowerCase dtoField.codeName}};
            }
        }
                {{/if}}
            {{/eq}}
            {{#eq dtoField.type 'DTO'}}
                {{#if dtoField.refPSAppDEMethodDTO}}
        //  {{lowerCase dtoField.codeName}}
        if({{pascalCase dtoField.refPSAppDEMethodDTO.codeName}}Help.getEnableCache()){
             _data.{{lowerCase dtoField.codeName}} = await {{pascalCase dtoField.refPSAppDEMethodDTO.codeName}}Help.getCacheData(context, source.{{lowerCase dtoField.codeName}});
        }else{
            if(source.hasOwnProperty('{{lowerCase dtoField.codeName}}')){
                _data.{{lowerCase dtoField.codeName}} = source.{{lowerCase dtoField.codeName}};
            }
        }
                {{/if}}
            {{/eq}}
        {{/if}}
    {{/each}}
        // 附加额外数据
        if (source && Object.keys(source).length > 0 && keys) {
            Object.keys(source).forEach((key: string) => {
                if (!keys.includes(key) && !excludes.includes(key)) {
                    _data[key] = source[key];
                }
            })
        }
        return _data;
    }

    /**
     * 转化数组(数据对象转化成DTO数组)
     *
     * @static
     * @param {IContext} context 应用上下文
     * @param {IParam[]} data 数据对象
     * @return {*} 
     * @memberof {{pascalCase dto.codeName}}Help
     */
    public static async toDtoArray(context: IContext, data: IParam[]) {
        const _data: any[] = [];
        if (data && Array.isArray(data) && data.length > 0) {
            for (let i = 0; i < data.length; i++) {
                const tempdata = await this.toDto(context, data[i]);
                _data.push(tempdata);
            }
        }
        return _data;
    }

    /**
     * 处理响应DTO对象
     *
     * @static
     * @param {IContext} context 应用上下文
     * @param {IParam} data 数据对象
     * @return {*} 
     * @memberof {{pascalCase dto.codeName}}Help
     */
    public static async set(context: IContext, data: IParam) {
        const _data: IParam = await this.toDataObj(context, data);
    {{#eq appEntity.storageMode 4}}
        const targetService: IEntityLocalDataService<I{{pascalCase appEntity.codeName}}> = await this.getService(context);
        await targetService.addLocal(context, _data);
    {{/eq}}
        return _data;
    }

    /**
     * 处理请求数据对象
     *
     * @static
     * @param {IContext} context 应用上下文
     * @param {IParam} data 数据对象
     * @return {*} 
     * @memberof {{pascalCase dto.codeName}}Help
     */
    public static async get(context: IContext, data: IParam = {}) {
    {{#eq appEntity.storageMode 4}}
        const targetService: IEntityLocalDataService<I{{pascalCase appEntity.codeName}}> = await this.getService(context);
        let localData: I{{pascalCase appEntity.codeName}} | null = await targetService.getLocal(context, data.{{lowerCase appEntity.keyPSAppDEField.codeName}});
        if (!localData) {
            localData = data;
        } else {
            localData.assign!(data);
        }
        return await this.toDto(context, localData);
    {{else}}
        return await this.toDto(context, data);
    {{/eq}}
    }

    /**
     * 获取缓存数据
     *
     * @static
     * @param {IContext} context 应用上下文
     * @param {string} srfkey 数据主键
     * @return {*} 
     * @memberof {{pascalCase dto.codeName}}Help
     */
    public static async getCacheData(context: IContext, srfkey: string) {
        {{#eq appEntity.storageMode 4}}
        const targetService: IEntityLocalDataService<I{{pascalCase appEntity.codeName}}> = await this.getService(context);
        const result = await targetService.getLocal(context, srfkey);
        if (result) {
            return await this.toDto(context, result);
        } else {
            return {};
        }
        {{else}}
        return {};
        {{/eq}}
    }

    /**
     * 获取缓存数组
     *
     * @static
     * @param {IContext} context 应用上下文
     * @return {*} 
     * @memberof {{pascalCase dto.codeName}}Help
     */
    public static async getCacheDataArray(context: IContext) {
        {{#eq appEntity.storageMode 4}}
        const targetService: IEntityLocalDataService<I{{pascalCase appEntity.codeName}}> = await this.getService(context);
        const result = await targetService.getLocals(context);
        if (result) {
            return await this.toDtoArray(context, result);
        } else {
            return [];
        }
        {{else}}
        return [];
        {{/eq}}
    }

    /**
     * 设置缓存数据
     *
     * @static
     * @param {IContext} context 应用上下文
     * @param {IParam} data 数据
     * @return {*} 
     * @memberof {{pascalCase dto.codeName}}Help
     */
    public static async setCacheData(context: IContext, data: IParam) {
        {{#eq appEntity.storageMode 4}}
        const targetService: IEntityLocalDataService<I{{pascalCase appEntity.codeName}}> = await this.getService(context);
        await this.set(context, data);
        {{/eq}}
    }

    /**
     * 设置缓存数组
     *
     * @static
     * @param {IContext} context 应用上下文
     * @param {any[]} data 数据
     * @return {*} 
     * @memberof {{pascalCase dto.codeName}}Help
     */
    public static async setCacheDataArray(context: IContext, data: any[]) {
        {{#eq appEntity.storageMode 4}}
        if (data && data.length > 0) {
            const targetService: IEntityLocalDataService<I{{pascalCase appEntity.codeName}}> = await this.getService(context);
            for (let i = 0; i < data.length; i++) {
                await this.set(context, data[i]);
            }
        }
        {{/eq}}
    }
}
{{/eq}}
{{/each}}